package com.lw;

import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

public class Response extends AbstractHttpServletResponse {
    private int status = 200;
    private String message = "OK";
    private Map<String, String> headers = new HashMap<>();

    //此处带入request，这样可以响应对应的请求
    private Request request;
    private OutputStream socketOutputStream;
    private ResponseServletOutputStream outputStream = new ResponseServletOutputStream();

    public Response(Request request) {
        this.request = request;
        try {
            this.socketOutputStream = request.getSocket().getOutputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void setStatus(int i, String s) {
        status = i;
        message = s;
    }

    public void complete() {
        //发送响应
        sendResponseLine();
        sendResponseHeader();
        sendResponseBody();
    }


    private byte SP = ' ';
    private byte CR = '\r';//回车
    private byte LF = '\n';//换行

    /**
     * 发送状态行
     * http版本 状态码 状态描述
     */
    private void sendResponseLine() {
        try {
            socketOutputStream.write(request.getProtocol().getBytes());
            socketOutputStream.write(SP);
            socketOutputStream.write(status);
            socketOutputStream.write(SP);
            socketOutputStream.write(message.getBytes());
            socketOutputStream.write(CR);
            socketOutputStream.write(LF);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 响应头部信息
     */
    private void sendResponseHeader() {

        if (!headers.containsKey("Content-Length")) {
            //content-length需要告诉浏览器返回的数据是多长，这样浏览器才能解析数据
            addHeader("Content-Length", "" + outputStream.getPos());
        }

        if(!headers.containsKey("Content-Type")){
            addHeader("Content-Type","text/plain;charset=utf-8");
        }


        headers.forEach((key, value) -> {
            try {
                socketOutputStream.write(key.getBytes());
                socketOutputStream.write(":".getBytes());
                socketOutputStream.write(value.getBytes());
                socketOutputStream.write(CR);
                socketOutputStream.write(LF);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });

        try {
            socketOutputStream.write(CR);
            socketOutputStream.write(LF);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 响应体
     */
    private void sendResponseBody() {
        try {
            socketOutputStream.write(outputStream.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void addHeader(String s, String s1) {
        headers.put(s, s1);
    }

    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return outputStream;
    }
}
